<template>
    <div class="marketing_seckill_create">
        <div class="header">
            <div class="title">活动设置</div>
            <el-form :rules="rules" :model="form" ref="formRef" label-width="auto">
                <el-form-item label="活动名称：" prop="name">
                    <el-input
                        class="width_400"
                        v-model="form.name"
                        maxlength="20"
                        show-word-limit
                        clearable
                        placeholder=""
                        autocomplete="off" />
                    <!-- <span class="tip">*不超过20字</span> -->
                </el-form-item>
                <el-form-item label="开始时间：" prop="startTime">
                    <el-date-picker
                        :disabled="!!id"
                        :disabled-date="
                            value => {
                                return value < new Date().getTime() - 24 * 60 * 60 * 1000;
                            }
                        "
                        class="width_400"
                        v-model="form.startTime"
                        type="datetime"
                        value-format="YYYY-MM-DD HH:mm:ss"
                        :default-time="new Date(2000, 1, 1, 0, 0, 0)"
                        placeholder="请选择日期" />
                </el-form-item>
                <el-form-item label="结束时间：" prop="endTime">
                    <el-date-picker
                        class="width_400"
                        v-model="form.endTime"
                        :disabled-date="
                            value => {
                                return value < new Date().getTime() - 24 * 60 * 60 * 1000;
                            }
                        "
                        type="datetime"
                        value-format="YYYY-MM-DD HH:mm:ss"
                        :default-time="new Date(2000, 1, 1, 0, 0, -1)"
                        placeholder="请选择日期" />
                </el-form-item>
                <el-form-item label="每人限购：" prop="purchaseLimit">
                    <el-checkbox :disabled="!!id" v-model="form.purchaseLimit">开启限购</el-checkbox>
                    <div v-show="form.purchaseLimit">
                        &emsp; &ensp;每人可购买&ensp;
                        <el-input-number
                            :disabled="!!id"
                            v-model="form.purchaseLimitNumber"
                            :precision="0"
                            :value-on-clear="null"
                            :min="1"
                            :max="9999999999"
                            controls-position="right" />
                        &ensp; 件
                    </div>
                </el-form-item>
                <el-form-item label="订单取消：" prop="noPayTime">
                    买家&ensp;
                    <el-input-number
                        :disabled="!!id"
                        v-model="form.noPayTime"
                        :precision="0"
                        :value-on-clear="null"
                        :min="5"
                        :max="15"
                        controls-position="right" />
                    &ensp; 分钟未支付，订单自动取消。
                    <span class="tip">(*秒杀活动是拍下减库存，为了减少库存的占用时间，建议商家合理设置)</span>
                </el-form-item>
            </el-form>
        </div>
        <div class="middle">
            <div class="title">活动商品</div>
            <el-form :rules="rules" :model="form" ref="goodsformRef">
                <el-form-item v-show="!form.goodsId" label="" prop="goodsId" label-width="30px">
                    <div class="empty_goods">
                        <ZwGeneralGoods
                            :disabled="!!id"
                            :isParticipationCol="true"
                            :isMulti="false"
                            :value="form.goodsId"
                            @handle-confirm="selectGoodsHandler">
                            <template #btn>
                                <el-button type="primary" :disabled="!!id">添加活动商品</el-button>
                            </template>
                        </ZwGeneralGoods>
                        <span class="tip">*只能添加一个商品参与秒杀活动</span>
                    </div>
                </el-form-item>
                <div v-show="form.goodsId">
                    <div class="product">
                        <div class="goods">
                            <img :src="selectGood.materialSrc" />
                            <div class="goods_right">
                                <div class="name">{{ selectGood.goodsName }}</div>
                                <div class="price">
                                    <span v-if="selectGood.goodsMinPrice === selectGood.goodsMaxPrice">
                                        ￥{{ floatDivide(selectGood.goodsMinPrice, 100) }}
                                    </span>
                                    <span v-else>
                                        ￥{{ floatDivide(selectGood.goodsMinPrice, 100) }} ~
                                        {{ floatDivide(selectGood.goodsMaxPrice, 100) }}
                                    </span>
                                </div>
                                <div class="stock">库存{{ selectGood.goodsStock }}</div>
                            </div>
                        </div>
                        <el-popconfirm :teleported="false" hide-icon @confirm="delGoodsHandler" title="确定删除?">
                            <template #reference>
                                <el-button v-show="!id"> 删除 </el-button>
                            </template>
                        </el-popconfirm>
                    </div>
                    <div class="middel">
                        <div>设置价格与库存</div>
                        <el-button type="primary" v-if="!singleSkuGoods" :disabled="!!id" @click="openGoodSkuDialog">
                            添加活动规格
                        </el-button>
                    </div>
                    <el-form-item label="" prop="goodsTableData" label-width="0"> </el-form-item>
                    <el-table style="width: 900px" empty-text="请选择参与的型号" :data="form.goodsTableData" stripe>
                        <el-table-column prop="skuName" label="规格" min-width="220" />
                        <el-table-column prop="skuPrice" label="原价(元)" min-width="95">
                            <template v-slot="{ row }">
                                {{ floatDivide(row.skuPrice, 100) }}
                            </template>
                        </el-table-column>
                        <el-table-column prop="spikePrice" label="秒杀价(元)" min-width="160">
                            <template v-slot="{ row }">
                                <ZwTableInputNumber
                                    placeholder="需小于原价"
                                    :style="{ width: '135px' }"
                                    :showInput="!id"
                                    :precision="2"
                                    :min="0"
                                    :max="floatDivide(row.skuPrice, 100)"
                                    :data="row.spikePrice"
                                    :errorMsg="row.spikePriceErrorMsg"
                                    @update="val => cellDataChange(val, row, 'spikePrice')"></ZwTableInputNumber>
                            </template>
                        </el-table-column>
                        <el-table-column prop="skuStock" label="库存" min-width="95" />
                        <el-table-column prop="spikeStockSurplus" label="秒杀库存" min-width="170">
                            <template v-slot="{ row }">
                                <ZwTableInputNumber
                                    v-if="!id"
                                    placeholder="不得大于现有库存"
                                    :showInput="true"
                                    :min="0"
                                    :max="row.skuStock"
                                    :data="row.spikeStockSurplus"
                                    :errorMsg="row.spikeStockSurplusErrorMsg"
                                    @update="val => cellDataChange(val, row, 'spikeStockSurplus')"></ZwTableInputNumber>
                                <div v-else>
                                    {{ row.spikeStockSurplus }}
                                    <el-icon class="edit_icon" @click="editStockHandler(row)"><Edit /></el-icon>
                                </div>
                            </template>
                        </el-table-column>
                        <el-table-column v-if="id" prop="spikeStockGoods" label="累计参加商品秒杀数" min-width="160" />
                        <el-table-column v-if="!id && !singleSkuGoods" prop="" label="操作" min-width="160">
                            <template v-slot="{ row }">
                                <el-button @click="skuDeleteHandler(row)">删除</el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                </div>
            </el-form>
        </div>
        <div class="bottom">
            <div class="bottom_btns">
                <el-button @click="router.go(-1)"> 取消 </el-button>
                <el-button type="primary" @click="createActicityHandler"> 确定 </el-button>
            </div>
        </div>
        <ZwChooseSku ref="ZwChooseSkuRef" @submit="getSku"></ZwChooseSku>

        <el-dialog v-model="dialog.stockVisible" title="修改库存" :before-close="dialogFormClose">
            <el-form ref="dialogFormRef" :rules="dialogFormRules" :model="dialogForm" label-position="left">
                <el-form-item label="" :label-width="0"> 目前秒杀库存：{{ dialogForm.currentStock }}</el-form-item>
                <el-form-item label="操作：" :label-width="70">
                    <el-radio-group v-model="dialogForm.method">
                        <el-radio label="add">增加</el-radio>
                        <el-radio label="sub">减少</el-radio>
                    </el-radio-group>
                </el-form-item>
                <el-form-item label="数量：" :label-width="70" prop="stock">
                    <el-input-number
                        v-model="dialogForm.stock"
                        v-if="dialogForm.method === 'add'"
                        :min="1"
                        :precision="0"
                        controls-position="right"
                        :max="dialogForm.allAddStock" />
                    <el-input-number
                        v-else
                        v-model="dialogForm.stock"
                        :precision="0"
                        :min="1"
                        controls-position="right"
                        :max="dialogForm.currentStock" />
                </el-form-item>
                <el-form-item label="" :label-width="0">
                    修改后库存：
                    <span v-if="dialogForm.method === 'add'">
                        {{ dialogForm.currentStock + dialogForm.stock }}
                    </span>
                    <span v-else>
                        {{
                            dialogForm.currentStock - dialogForm.stock < 0
                                ? 0
                                : dialogForm.currentStock - dialogForm.stock
                        }}
                    </span>
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="cancelStockhandler">取消</el-button>
                    <el-button type="primary" @click="comfirmStockhandler">确认</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>

<script setup name="seckillCreate">
import { reactive, onMounted, onUnmounted, ref } from 'vue';
import request from '@/request/index';
import { ElMessage } from 'element-plus';
import { useRouter, useRoute } from 'vue-router';
import { setLayout, resetLayout } from '@/hooks/layout';
import { floatDivide, floatMultiply } from '@/commons/utils';

const router = useRouter();
const route = useRoute();
const query = route.query;
let id = ref(null);
id.value = route.query.id || '';
const formRef = ref();
const goodsformRef = ref();
let form = reactive({
    name: null,
    startTime: '',
    endTime: '',
    purchaseLimit: null,
    purchaseLimitNumber: 1,
    noPayTime: 5,
    goodsId: '',
    goodsTableData: []
});
const validateFormFileds = ({ fullField, message }, value, callback) => {
    switch (fullField) {
        case 'purchaseLimit':
            if (value && !form.purchaseLimitNumber) {
                return callback(new Error(message));
            }
            callback();
            break;
        case 'endTime':
            if (value && value <= form.startTime) {
                return callback(new Error(message));
            }
            callback();
            break;
        default:
            callback();
            break;
    }
};
const rules = reactive({
    name: [{ required: true, message: '活动名称必填', trigger: ['blur', 'change'] }],
    startTime: [{ required: true, message: '活动开始时间必填', trigger: ['blur', 'change'] }],
    endTime: [
        { required: true, message: '活动结束时间必填', trigger: ['blur', 'change'] },
        { validator: validateFormFileds, message: '活动结束时间须大于活动开始时间', trigger: ['blur', 'change'] }
    ],
    purchaseLimit: { validator: validateFormFileds, message: '限购数必须大于0', trigger: ['blur', 'change'] },
    noPayTime: [{ required: true, message: '订单取消时间必填', trigger: ['blur', 'change'] }],
    goodsId: [{ required: true, message: '请选择活动商品', trigger: ['blur', 'change'] }],
    goodsTableData: [{ required: true, message: '请设置活动商品价格和库存', trigger: ['blur', 'change'] }]
});

const ZwChooseSkuRef = ref(null);
const currentGoodsAllData = ref([]);
let selectGood = reactive({
    goodsName: '',
    goodsMinPrice: '',
    goodsMaxPrice: '',
    goodsStock: '',
    materialSrc: ''
});

const dialogFormRef = ref();
const dialog = reactive({
    stockVisible: false
});
const dialogForm = reactive({
    // add 加 sub 减
    method: 'add',
    currentStock: null,
    stock: null
});

const validateStocksFiled = ({ fullField, message }, value, callback) => {
    if (!value) {
        return callback(new Error('修改秒杀库存必须为正整数'));
    }
    if (
        dialogForm.method === 'add' &&
        dialogForm.currentStock + value > dialogForm.allAddStock + dialogForm.currentStock
    ) {
        return callback(new Error(`秒杀库存不得超过现有库存`));
    }
    if (dialogForm.method === 'sub' && dialogForm.currentStock - value < 0) {
        return callback(new Error('秒杀库存不得小于0'));
    }
    callback();
};
const dialogFormRules = reactive({
    stock: [
        { required: true, message: '修改秒杀库存必须为正整数', trigger: 'blur' },
        { validator: validateStocksFiled, trigger: 'blur' }
    ]
});

if (id.value) {
    request('seckillDetailServ', { id: route.query.id }).then(res => {
        const obj = res.data || {};
        form.name = obj.name;
        form.startTime = obj.startTime;
        form.endTime = obj.endTime;
        form.purchaseLimit = obj.purchaseLimit === 2 ? true : false;
        form.purchaseLimitNumber = obj.purchaseLimitNumber;
        form.noPayTime = obj.noPayTime;
        form.goodsId = obj.goodsId;
        selectGood.goodsName = obj.goods.name;
        selectGood.goodsMinPrice = obj.goods.goodsMinPrice;
        selectGood.goodsMaxPrice = obj.goods.goodsMaxPrice;
        selectGood.goodsStock = obj.goods.stock;
        selectGood.materialSrc = obj.goods.img;
        form.goodsTableData = obj.skuInfo.map(x => {
            const skuNamesArr = x.specs;
            let skuName = '';
            skuNamesArr.forEach((e, idx) => {
                skuName += idx === skuNamesArr.length - 1 ? e : e + '; ';
            });
            return Object.assign({}, x, {
                skuName: skuName,
                spikePrice: floatDivide(x.spikePrice, 100),
                spikeStockSurplus: x.spikeStockSurplus
            });
        });
    });
}

let singleSkuGoods = ref(false);
const selectGoodsHandler = row => {
    form.goodsId = row.id;
    selectGood = Object.assign(selectGood, row, { materialSrc: (row.materialSrc || [])[0]?.materialSrc });
    currentGoodsAllData.value = row.skuInfo;
    if (row.skuInfo?.length > 1) {
        ZwChooseSkuRef.value.onOpen(row.skuInfo, []);
        singleSkuGoods.value = false;
    } else {
        singleSkuGoods.value = true;
        pushGoodsSku(row.skuInfo);
    }
};

const pushGoodsSku = arr => {
    form.goodsTableData = arr.map(x => {
        // const skuNamesArr =
        //     Array.from(
        //         Array.from(x.skuExt || [], e => e.specAttr) || [],
        //         ele => ele.specAttrKeyName + ele.attributeValue
        //     ) || [];
        const skuNamesArr = x.specs;
        let skuName = '';
        skuNamesArr.forEach((e, idx) => {
            skuName += idx === skuNamesArr.length - 1 ? e : e + '; ';
        });
        return Object.assign({}, x, {
            skuName: skuName,
            spikePrice: null,
            spikeStockSurplus: null
        });
    });
    goodsformRef?.value?.validateField('goodsTableData');
};

const delGoodsHandler = () => {
    form.goodsTableData.length = 0;
    selectGood = {};
    form.goodsId = '';
};

const skuDeleteHandler = row => {
    form.goodsTableData = form.goodsTableData.filter(x => {
        return x.id != row.id;
    });
};

const openGoodSkuDialog = () => {
    const selectedSkuId = Array.from(form.goodsTableData, x => x.id);
    ZwChooseSkuRef.value.onOpen(currentGoodsAllData.value, selectedSkuId);
};
const getSku = skuArr => {
    pushGoodsSku(skuArr);
};

const createActicityHandler = () => {
    formRef.value.validate(async valid => {
        if (valid) {
            goodsformRef.value.validate(async val => {
                if (val) {
                    const para = Object.assign({ seckillGoods: [], id: Number(id.value) }, form);
                    if (form.purchaseLimit) {
                        para.purchaseLimit = 2;
                    } else {
                        delete para.purchaseLimitNumber;
                        para.purchaseLimit = 1;
                    }
                    const errorRow = form.goodsTableData.find(x => x.spikePriceErrorMsg || x.spikeStockSurplusErrorMsg);
                    const emptyValue = form.goodsTableData.find(x => !x.spikePrice || !x.spikeStockSurplus);
                    if (!id.value && (errorRow || emptyValue)) {
                        if (emptyValue) {
                            cellDataChange(emptyValue.spikePrice, emptyValue, 'spikePrice');
                            cellDataChange(emptyValue.spikeStockSurplus, emptyValue, 'spikeStockSurplus');
                        }
                        return;
                    }
                    form.goodsTableData.forEach(x => {
                        let ele = {
                            skuId: x.id,
                            spikePrice: floatMultiply(x.spikePrice, 100),
                            spikeStockSurplus: x.spikeStockSurplus
                        };
                        if (id.value) {
                            ele.seckillGoodsId = x.seckillGoodsId;
                        }
                        if (x.changeStock > 0) {
                            ele.method = 'add';
                            ele.spikeStockSurplus = Math.abs(x.changeStock);
                        } else if (x.changeStock < 0) {
                            ele.method = 'sub';
                            ele.spikeStockSurplus = Math.abs(x.changeStock);
                        }
                        para.seckillGoods.push(ele);
                    });
                    if (!id.value) {
                        delete para.id;
                    }
                    delete para.goodsTableData;
                    const requestName = id.value ? 'editSeckillServ' : 'createSeckillServ';
                    request(requestName, para).then(res => {
                        if (res.data) {
                            ElMessage.success(`${id.value ? '编辑' : '创建'}成功`);
                            router.go(-1);
                        }
                    });
                }
            });
        }
    });
};

const cellDataChange = (val, row, key) => {
    row[key] = val;
    switch (key) {
        case 'spikePrice':
            if (!val) {
                row[key + 'ErrorMsg'] = '秒杀价不能为0';
            } else if (val >= floatDivide(row.skuPrice, 100)) {
                row[key + 'ErrorMsg'] = '秒杀价需小于原价';
            } else {
                row[key + 'ErrorMsg'] = '';
            }
            break;
        case 'spikeStockSurplus':
            if (!val) {
                row[key + 'ErrorMsg'] = '秒杀库存不能为0';
            } else if (val > row.skuStock) {
                row[key + 'ErrorMsg'] = '秒杀库存不能大于现有库存';
            } else {
                row[key + 'ErrorMsg'] = '';
            }
            break;
        default:
            break;
    }
};

const editStockHandler = row => {
    dialog.stockVisible = true;
    dialogForm.currentStock = row.spikeStockSurplus;
    dialogForm.stock = 1;
    dialogForm.method = 'add';
    dialogForm.allAddStock = row.skuStock;
    dialogForm.id = row.id;
};

const comfirmStockhandler = () => {
    dialogFormRef.value.validate(async valid => {
        if (valid) {
            let row = form.goodsTableData.find(x => x.id === dialogForm.id);
            dialog.stockVisible = false;
            if (dialogForm.method == 'add') {
                // 添加更新库存标识
                row.changeStock = (row.changeStock || 0) + dialogForm.stock;
                // 更新秒杀库存
                row.spikeStockSurplus = row.spikeStockSurplus + dialogForm.stock;
                // 更新sku秒杀库存
                row.skuStock = row.skuStock - dialogForm.stock;
                // 更新累计秒杀库存
                row.spikeStockGoods = row.spikeStockGoods + dialogForm.stock;
            } else {
                row.changeStock = (row.changeStock || 0) - dialogForm.stock;
                row.spikeStockSurplus = row.spikeStockSurplus - dialogForm.stock;
                row.skuStock = row.skuStock + dialogForm.stock;
                row.spikeStockGoods = row.spikeStockGoods - dialogForm.stock;
            }
        }
    });
};

const cancelStockhandler = () => {
    dialogFormRef.value.resetFields();
    dialog.stockVisible = false;
};

const dialogFormClose = done => {
    dialogFormRef.value.resetFields();
    done();
};

onMounted(() => {
    setLayout();
});
onUnmounted(() => {
    resetLayout();
});
</script>
<style lang="scss" src="./style.scss" scoped></style>
